/*
 Authors: ZhangXuelian
 	
 
 Changes:
 	
	
*/

#include "../libmain/gobal.h"

//Lyc
int pack_data_web_register_to_server(void * user_data)
{
	//printf("[INFO][web][sdk][%s] : Enter 3\n", __func__);

	//SDK_IM * c = (SDK_IM *)user_data;

	//SDK_HEART *heart  = malloc(sizeof(SDK_HEART));
	//heart->magic      = PROTOCOL_IM_WEB_MAGIC;	//Web magic Âë
	//heart->version    = IM_PROTOCOL_VERSION;
	//heart->encript    = 1;
	//heart->cmd        = IM_CMD_REGISTER;		//Í³Ò»×¢²áÃüÁî 1001
	//heart->body_len   = 0;
	//heart->sender_imid = 0;
	//heart->imid       = c->imid;
	//heart->devicetype = c->devicetype;

	//if (!put_protocol_packet_to_send(&c->client.buf_list, (char*)heart, sizeof(SDK_HEART), 0))
	//{
	//	printf("[ERROR][web][sdk][%s] : Failed, Put Web register data to send failed!\n", __func__);
	//	free(heart);
	//	return ERROR_INTERNAL;
	//}

	//printf("[INFO][web][sdk][%s] : Success ,Put Web register data to send OK!\n", __func__);
	return ERROR_OK;
}

//5秒内检查注册应答
void thread_check_register_ack()
{
    LOGE("[INFO][sdk][%s] : Enter\n", __func__);

    SDK_CONTENT * c = &g_sdk_content;
    int loop_count = 0;

    for (loop_count = 0; loop_count < 3; loop_count++)
    {
        if (c->comm.is_register_ok)
        {
            break;
        }
        sleep(1);
    }

	//pthread_mutex_unlock(&c->im.resgister_mutex);
    //如果5秒后还没有收到注册应答则上抛101错误给安卓层
    if (false == c->comm.is_register_ok)
    {
		//pthread_exit(NULL);
		usleep(1000);
		close(c->im.client.fd);
        c->comm.notify.on_im_error_notify(101);	//101 网络异常
		c->im.client.el->stop = 1;
		return;
    }
	//pthread_exit(NULL);
    return;
}

void check_register_ack()
{
	SDK_CONTENT * c = &g_sdk_content;
    //pthread_t thread_id;
    pthread_create(&(c->im.check_resgister_pid), NULL, &thread_check_register_ack, NULL);
}

//安卓向服务端注册 add by Lyc
int pack_data_android_register_to_server(void * user_data)
{
	LOGE("[INFO][sdk][%s] : Enter\n", __func__);
	SDK_CONTENT * sdk = &g_sdk_content;
	SDK_IM * c = (SDK_IM *)user_data;

	if (c->imei == NULL)
		return ERROR_INTERNAL;

	
	char *json_to_gateway = NULL;
	cJSON * root = cJSON_CreateObject();
	cJSON * fld = cJSON_CreateObject();

	cJSON_AddNumberToObject(root, "magic", PROTOCOL_IM_AND_MAGIC);
	cJSON_AddNumberToObject(root, "command", IM_CMD_REGISTER);
	cJSON_AddItemToObject(root, "data", fld);
	cJSON_AddStringToObject(fld, "imei", c->imei);
	cJSON_AddStringToObject(fld, "iccid", c->iccid);
	cJSON_AddStringToObject(fld, "name", c->name);
	json_to_gateway = cJSON_Print(root);
	int len = strlen(json_to_gateway);

	int alldatalen = sizeof(SDK_JAVA_SEND_MSG) + len;
	SDK_JAVA_SEND_MSG * senddata = malloc(alldatalen);
	if (NULL == senddata)
	{
		LOGI("[INFO][mdm][%s] : senddata is null\n", __func__);
		return -1;
	}
	// 22 + data
	senddata->head.magic = PROTOCOL_IM_AND_MAGIC;
	senddata->head.version = IM_PROTOCOL_VERSION;  // 旧的登录流程和新的登录流程的版本号不一样  1：旧登录流程  2:新的登录流程
	senddata->head.encript = 1;
	senddata->head.cmd = IM_CMD_REGISTER;
	senddata->head.body_len = len;
	senddata->head.sender_imid = 0;	
	senddata->head.target_imid = 0;  
	senddata->head.devicetype = c->devicetype;	//安卓的设备类型 : 1
	
	memcpy(senddata->data, json_to_gateway, len);

	int error = 0;
	if ((error != pack_data_device_send_im_data_to_server(&c->client.buf_list, (char*)senddata, alldatalen)))
	{
		my_safe_free(senddata);
		LOGI("[INFO][mdm][%s] : error = %d\n", __func__, error);
		return error;
	}

	my_safe_free(senddata);

	LOGI("[INFO][Android][mdm][%s] : Success ,Put android register data to send OK! fd =%d\n", __func__, sdk->im.client.fd);
	cJSON_Delete(root);
	my_safe_free(json_to_gateway);
	return ERROR_OK;
}

// Java向服务端注册, add by Lyc
int pack_data_java_register_to_server(void * user_data, char * service_name)
{
	//printf("[INFO][sdk][%s] : Enter 3\n", __func__);
	//SDK_IM * c = (SDK_IM *)user_data;
	//int namelen = my_safe_strlen(service_name);
	//int datalen = sizeof(SDK_HEART) + namelen;
	//char * data  = (char*)malloc(datalen);

	//SDK_HEART *heart  = malloc(sizeof(SDK_HEART));
	//heart->magic      = PROTOCOL_IM_JAVA_MAGIC; //JAVA magic Âë
	//heart->version    = IM_PROTOCOL_VERSION;
	//heart->encript    = 1;
	//heart->cmd        = IM_CMD_REGISTER;	//Í³Ò»×¢²áÃüÁî 1003
	//heart->body_len	  = namelen;
	//heart->sender_imid = 0;
	//heart->imid       = 0;	//java has no imid. 
	//heart->devicetype = 0;  //java has no devicetype

	//memcpy(data, heart, sizeof(SDK_HEART));
	//memcpy(data + sizeof(SDK_HEART), service_name, namelen);
	//
	//if (!put_protocol_packet_to_send(&c->client.buf_list, data, datalen, 0))
	//{
	//	printf("[ERROR][sdk][%s] : ERROR, java register failed to put_protocol_packet_to_send\n", __func__);
	//	free(data);
	//	return ERROR_INTERNAL;
	//}

	//printf("[INFO][sdk][%s] : Success, java register to put_protocol_packet_to_send\n", __func__);
	return ERROR_OK;
}


int pack_data_device_send_im_data_to_server(SEND_PACKETS * c, char * p_src, int content_len)
{
	LOGI("[INFO][mdm][%s] : Enter	03\n", __func__);
	if (!put_protocol_packet_to_send(c, p_src, content_len, 0))
	{
		LOGI("[INFO][mdm][%s] : ERROR_INTERNAL\n", __func__);
		return ERROR_INTERNAL;	//此处无需释放p_src, 外部释放了
	}
	LOGI("[INFO][mdm][%s] : Exit	04\n", __func__);
	return ERROR_OK;
}



// add by Lyc
// 功能 : 安卓 发送数据到 C服务器
// 参数 : 
//		  void * user_data    : SDK_IM 类型
//		  char* imid		  : 目标的imid
//		  char*	servicename   : 后端java提供的服务名称
//		  int name_len        : servicename的长度
//		  unsigned short cmd  : 后端java提供的命令字
//        char* pb_package    : 需要发送的数据
//        int len             : 上面数据的长度
// 返回  : 
// 内存模型:
// 
//	    | namelen          |   sender_imid_len  | target_imid_len    |               datalen             |  
//		|<-----name----->  |<----sender_imid -->|<-- target_imid --> |<------------  data  ------------> |

int android_send_im_data_to_server(void * user_data,
									char* imid,
									char * servicename,
									int name_len,
									unsigned short cmd,
									char * pb_package,
									int len)
{
	LOGI("[INFO][mdm][%s] : Enter	01\n", __func__);

	if (NULL == user_data)
	{
		LOGI("[INFO][mdm][%s] : user_data is null\n", __func__);
		return -1;
	}


	SDK_IM * c = (SDK_IM *)user_data;

	int alldatalen = sizeof(SDK_JAVA_SEND_MSG) +  len;
	SDK_JAVA_SEND_MSG * senddata = malloc(alldatalen);
	if (NULL == senddata)
	{
		LOGI("[INFO][mdm][%s] : senddata is null\n", __func__);
		return -1;
	}
	// 22 + data
	senddata->head.magic = PROTOCOL_IM_AND_MAGIC;
	senddata->head.version = IM_PROTOCOL_VERSION;
	senddata->head.encript = 1;
	senddata->head.cmd = cmd;
	senddata->head.body_len = len;
	senddata->head.sender_imid = 0;		//这里是安卓用户自己的imid长度
	senddata->head.target_imid = 0;   //这里目标的imid的长度
	senddata->head.devicetype = c->devicetype;	//安卓的设备类型 : 1


	LOGE("[INFO][mdm][%s] :------------------ data to send ----------------------", __func__);
	LOGE("[INFO][mdm][%s] : cmd             = %d", __func__, cmd);
	LOGE("[INFO][mdm][%s] : servicename     = %s", __func__, servicename);
	LOGE("[INFO][mdm][%s] : servicename len = %d", __func__, name_len);
	LOGE("[INFO][mdm][%s] : pb_package      = %s", __func__, pb_package);
	LOGE("[INFO][mdm][%s] : pb len          = %d", __func__, len);
	LOGE("[INFO][mdm][%s] : sender_imei     = %s", __func__, c->imei);
	LOGE("[INFO][mdm][%s] : sender_iccid     = %s", __func__, c->iccid);
	LOGE("[INFO][mdm][%s] : sender_name     = %s", __func__, c->name);
	LOGE("[INFO][mdm][%s] : target_imid     = %s", __func__, imid);
	LOGE("[INFO][mdm][%s] :------------------ data to send ----------------------", __func__);

	memcpy(senddata->data, pb_package, len);

	int error = 0;
	if ((error != pack_data_device_send_im_data_to_server(&c->client.buf_list, (char*)senddata, alldatalen)))
	{
		my_safe_free(senddata);
		LOGI("[INFO][mdm][%s] : error = %d\n", __func__, error);
		return error;
	}

	my_safe_free(senddata);
	LOGI("[INFO][mdm][%s] : Exit  \n", __func__);
	return ERROR_OK;
}


//int android_send_im_data_to_server(void * user_data,
//								   int imid,
//								   char * servicename,
//								   int name_len,
//								   unsigned short cmd, 
//								   char * pb_package, 
//								   int len)
//{
//	LOGI("[INFO][sdk][%s] : Enter	01\n", __func__);
//
//	if (NULL == user_data)
//	{
//		LOGI("[INFO][sdk][%s] : user_data is null\n", __func__);
//		return -1;
//	}
//
//	SDK_IM * c = (SDK_IM *)user_data;	
//	SDK_SEND_MSG * senddata = malloc(sizeof(SDK_SEND_MSG) + name_len + len);
//	if (NULL == senddata)
//	{
//		LOGI("[INFO][sdk][%s] : senddata is null\n", __func__);
//		return -1; 
//	}
//
//	senddata->head.magic      = PROTOCOL_IM_AND_MAGIC;
//	senddata->head.version    = IM_PROTOCOL_VERSION;
//	senddata->head.encript    = 1;
//	senddata->head.cmd        = cmd;
//	senddata->head.body_len	  = name_len + len;
//	senddata->head.sender_imid = c->imid;		//这里是安卓用户自己的imid
//	senddata->head.target_imid = imid;   		//这里目标的imid
//	senddata->head.devicetype = c->devicetype;	//安卓的设备类型 : 1
//	senddata->service_name_len = name_len;
//
//	LOGI("[INFO][sdk][%s] :------------------ data to send ----------------------", __func__);
//	LOGI("[INFO][sdk][%s] : cmd             = %d", __func__, cmd);
//	LOGI("[INFO][sdk][%s] : servicename     = %s", __func__, servicename);
//	LOGI("[INFO][sdk][%s] : servicename len = %d", __func__, name_len);
//	LOGI("[INFO][sdk][%s] : pb_package      = %s", __func__, pb_package);
//	LOGI("[INFO][sdk][%s] : pb len          = %d", __func__, len);
//	LOGI("[INFO][sdk][%s] : imid            = %d", __func__, c->imid);
//	LOGI("[INFO][sdk][%s] : devicetype      = %d", __func__, c->devicetype);
//	LOGI("[INFO][sdk][%s] :------------------ data to send ----------------------", __func__);
//
//	memcpy(senddata->data, servicename, name_len);
//	memcpy(senddata->data + name_len, pb_package, len);
//
//	int sendlen = sizeof(SDK_SEND_MSG) + name_len + len;// 发送包的总长度 = 包头 + "服务名称"的长度 + 数据长度
//	int error;
//
//	if ((error = pack_data_device_send_im_data_to_server(&c->client.buf_list, (char*)senddata, sendlen)))
//	{
//		free(senddata);
//		LOGI("[INFO][sdk][%s] : error = %d\n", __func__,error);
//		return error;
//	}
//	LOGI("[INFO][sdk][%s] : Exit  \n", __func__);
//	return ERROR_OK;
//}

// add by Lyc
// 功能 : Java 发送数据到 C服务器
// 参数 : 
//        void * user_data    : SDK_IM 类型
//		  int imid            : 目标安卓用户的imid	
//		  unsigned short cmd  : 安卓端提供的命令字
//        char* pb_package    : 需要发送的数据
//        int len             : 上面数据的长度
//		  int flag			  : 0-通知所有设备, 1-只通知安卓手机, 2-只通知PC端, 3-只通知Web 
//返回  : 
int java_send_im_data_to_server(void * user_data, 
								int imid, 
								unsigned short cmd, 
								char * pb_package, 
								int len,
								int flag)
{
	//printf("[INFO][sdk][%s] : Enter\n", __func__);
	//
	//SDK_IM * c = (SDK_IM *)user_data;

	//int sendlen = SDK_HEART_LENGTH + len;
	//SDK_JAVA_SEND_MSG * senddata =  malloc(sendlen);
	//
	//senddata->head.magic      = PROTOCOL_IM_JAVA_MAGIC;
	//senddata->head.version    = IM_PROTOCOL_VERSION;
	//senddata->head.encript    = 1;
	//senddata->head.cmd        = cmd;
	//senddata->head.body_len	  = len;
	//senddata->head.seq        = time(NULL);
	//senddata->head.imid       = imid;	//目标的imid
	//senddata->head.devicetype = flag;   //目标的设备类型, 设备类型,0-所有设备, 1-安卓, 2-PC, 3-Web, 4-Java
	//printf("-----------------------\n");
	//printf("cmd		   = %d\n", cmd);
	//printf("imid       = %d\n", imid);
	//printf("pb_package = %s\n", pb_package);
	//printf("len		   = %d\n", len);
	//printf("flag	   = %d\n", flag);
	//printf("-----------------------\n");
	//memcpy(senddata->data, pb_package, len);

	//int error;
	//if ((error = pack_data_device_send_im_data_to_server(&c->client.buf_list, (char*)senddata, sendlen)))
	//{
	//	return error;
	//}

	return ERROR_OK;
}


// add by Lyc
// 区分了 安卓 心跳 和 java 心跳
SDK_HEART * buildHeart()
{
	SDK_HEART * heart = malloc(sizeof(SDK_HEART));

	SDK_CONTENT * c = &g_sdk_content;
	int temp = c->im.devicetype;
	switch (temp)
	{
	case REG_ANDROID:
		heart->magic = PROTOCOL_IM_AND_MAGIC;	// android magic
		break;
	case REG_JAVA:
		heart->magic = PROTOCOL_IM_JAVA_MAGIC;  // java magic
		break;
	case REG_WEB:
		heart->magic = PROTOCOL_IM_WEB_MAGIC;	// web magic
		break;
	default:
		break;
	}

	heart->version    = IM_PROTOCOL_VERSION;
	heart->encript    = 1;
	heart->body_len	  = 0;
	heart->cmd        = IM_CMD_HEARTBEAT; //心跳命令 : 2006
	heart->sender_imid = 0;//c->im.imid;
	heart->target_imid = 0;//c->im.imid;
	heart->devicetype = c->im.devicetype;

	return heart;
}

int device_data_web_register_to_server(void * user_data)
{
	printf("[INFO][web][sdk][%s] : Enter\n", __func__);
	//SDK_IM * c = (SDK_IM *)user_data;

	int error = 0;
	if ((error != pack_data_web_register_to_server(user_data)))
	{
		return error;
	}

	return ERROR_OK;
}

int device_data_android_register_to_server(void * user_data)
{
	LOGI("[INFO][sdk][%s] : Enter\n", __func__);

	int error = 0;
	if ((error != pack_data_android_register_to_server(user_data)))
	{
		return error;
	}

	return ERROR_OK;
}

int device_data_java_register_to_server(void * user_data,char * service_name)
{
	LOGI("[INFO][sdk][%s] : Enter\n", __func__);
	//SDK_IM * c = (SDK_IM *)user_data;

	int error = 0;
	if ((error != pack_data_java_register_to_server(user_data, (char*)service_name)))
	{
		return error;
	}

	return ERROR_OK;
}


// add by Lyc.  专门发送心跳的接口
int device_send_im_heartbeat(AE_EVENT_LOOP * event_loop, long long id, void * client_data)
{
	LOGE("[INFO][mdm][%s] : Enter \n", __func__);
	UNUSED(event_loop);
    UNUSED(id);
    UNUSED(client_data);

	SDK_CONTENT * c = &g_sdk_content;
	// change by tqq 2018.10.28 15:12 注册成功才发送心跳
	if(!c->comm.is_register_ok)
		return 0;

    if (c->suppress_heartbeat)
    {
        //LOGI("[INFO][sdk] ### NO SEND HEARTBEAT!!! ###");
        c->suppress_heartbeat = false;
    }
    else
    {
        SDK_HEART * heart = buildHeart();
        int error = 0;
        if ((error != pack_data_device_send_im_data_to_server(&c->im.client.buf_list, (char*)heart, sizeof(SDK_HEART))))
        {
            LOGI("[ERROR][mdm][%s] : ERROR, faild to send IM heartbeat!\n", __func__);
			my_safe_free(heart);
            return error;
        }
		LOGI("[INFO][mdm][%s] : success send IM heartbeat!  (mainthread = %d) \n", __func__,c->comm.mainthread);
		my_safe_free(heart);   //因为修改了发送机制，需要手动释放心跳包内存 2018.11.27 
    }

	c->im.ping = time(NULL);
	if ((c->im.ping - c->im.pong) > 16) //超过15秒即断开重连(3次心跳间隔)
	{
		LOGI("[ERROR][mdm][%s] :  heartbeat pong timeout 16 !\n", __func__);
		c->im.is_connecting = 1;   
		c->im.net_status = 0;
		c->im.client.el->stop = 1;
		c->comm.is_register_ok = false;
	}
	

    return HEARTBEAT_INTERVAL;
}

int device_timer_counter(AE_EVENT_LOOP * event_loop, long long id, void * client_data)
{
	SDK_CONTENT * c = &g_sdk_content;
	//c->comm.notify.on_im_error_notify(110);	
}

// 服务端发送数据到此处,进行处理, Lyc
void handle_im_recv_data(void * client, unsigned short cmd, unsigned int sender_imid_len, unsigned int target_imid_len, char * content, unsigned int content_len)
{
	LOGE("[INFO][mdm][%s] : Enter 006\n", __func__);
	SDK_CONTENT * c = &g_sdk_content;
	int temp = c->im.devicetype;
	switch (temp)
	{
	case REG_ANDROID:
		LOGE("[INFO][mdm][%s] :  Success, Android recv: content = %s, recv len = %d\n", __func__, content, content_len);
		break;
	case REG_JAVA:
		LOGE("[INFO][mdm][%s] :  Success, Java    recv: content = %s, recv len = %d\n", __func__, content, content_len);
		break;
	case REG_WEB:
		LOGE("[INFO][mdm][%s] :  Success, Web     recv: content = %s, recv len = %d\n", __func__, content, content_len);
		break;
	default:
		break;
	}

	LOGE("[INFO][mdm][%s] : Ready to notify Android !!!,   sender_imid_len = %d\n", __func__, sender_imid_len);
	LOGE("[INFO][mdm][%s] : Ready to notify Android !!!,   target_imid_len = %d\n", __func__, target_imid_len);

	char * sender_imid = malloc(sender_imid_len + 1);
	char * target_imid = malloc(target_imid_len + 1);
	int pbdatalen = content_len - sender_imid_len - target_imid_len;
	char * pbdata = malloc(pbdatalen + 1);

	if (sender_imid && target_imid && pbdata)
	{
		memset(sender_imid, 0, sender_imid_len + 1);
		memcpy(sender_imid, content, sender_imid_len);

		memset(target_imid, 0, target_imid_len + 1);
		memcpy(target_imid, content + sender_imid_len, target_imid_len);

		memset(pbdata, 0, pbdatalen + 1);
		memcpy(pbdata, content + sender_imid_len + target_imid_len, pbdatalen);

		c->comm.notify.on_receive_im_msg(cmd, sender_imid, target_imid, pbdata, pbdatalen);

		//remove by tan 2018.10.22 10:01
		//free(sender_imid );
		//free(target_imid );
		//free(pbdata );
	}
	else
	{
		my_safe_free(sender_imid);
		my_safe_free(target_imid);
		my_safe_free(pbdata);
	}
	return;
}

//当收到服务器传来的被迫下线命令。回调jni被迫下面函数
void handle_im_force_offline(void *client)
{
	LOGI("[INFO][sdk][%s] : Enter\n", __func__);
	SDK_CONTENT * c = &g_sdk_content;
	c->comm.notify.on_im_error_notify(103);	//103 被迫下线
	c->im.login_status = 0;
	//为了退出主循环   add by tqq 2018.10.22 16:49

	//c->im.client.el->stop = 1;

}
// 当注册完成后,开始启动心跳, 内部区分了 安卓 心跳 和 java 心跳, Lyc
void handle_im_register_resp(void * client, char * content, unsigned int content_len)
{
	LOGI("[INFO][mdm][%s] : Enter\n", __func__);
	SDK_CONTENT * c = &g_sdk_content;
	//设置注册应答消息已返回标志
	c->comm.is_register_ok = true;
	//c->comm.notify.on_im_error_notify(100);	//100 网络正常

	//将登陆成功的信息返回给app
	handle_im_recv_data(c, IM_CMD_REGISTER_SUCCESS,0,0, content, content_len);

	c->im.pong = time(NULL); //注册时初始化心跳包回应的时间
	c->im.try_connect_time = 0;
	c->im.is_connecting = 0;

	LOGI("[INFO][mdm][%s] : [========> Register Success <========] \n", __func__);

	if (0 == c->im.time_event_status)
	{
		// 发送心跳包间隔时间为60秒
		if (ae_create_time_event(c->im.client.el, HEARTBEAT_INTERVAL, device_send_im_heartbeat, NULL, NULL) == AE_ERR)
		{
			LOGI("[ERROR][mdm][%s] : ERROR, Failed to create time event!!!\n", __func__);
			// exit(1);
			return;
		}

		// 定时500毫秒计数
		if (ae_create_time_event(c->im.client.el, TIMER_INTERVAL, device_timer_counter, NULL, NULL) == AE_ERR)
		{
			LOGI("[ERROR][sdk][%s] : ERROR, Failed to create device_timer_counter event!!!\n", __func__);
			return;
		}


		c->im.time_event_status = 1;  //防止重复创建心跳定时器
		LOGI("[INFO][mdm][%s] : create heartbeat\n", __func__);
	}


	// TODO
	// 给状态线程一个状态
	LOGI("[INFO][mdm][%s] : Exit\n", __func__);
}

//由于JAVA未登陆CServer，因此注册失败，向安卓层上抛错误码104
void handle_im_java_unusable(void * client, char * content, unsigned int content_len)
{
    LOGE("[INFO][sdk][%s] : Enter\n", __func__);

    SDK_CONTENT * c = &g_sdk_content;
    c->comm.notify.on_im_error_notify(104);	//104 JAVA未登陆CServer
	// add by tqq 2018.10.23 14:11
	//c->im.net_status = 0;
	//c->im.client.el->stop = 1;
}


// 未使用
void * thread_check_net_temp()
{
	SDK_CONTENT * c = &g_sdk_content;
	int ok_count = 0;
	int failed_count = 0;
	while (c->comm.is_active_offline == 0)	//如果没有进行主动断开连接的操作，则循环判断网络情况
	{
		LOGI("[INFO][sdk] thread_check_net looping ");
		sleep(5);

			if (!is_socket_writeable(c->im.client.fd, 0))	//如果不可写,说明断网
			{
				c->im.net_status = 0;
				LOGI("[INFO][sdk] thread_check_net failed");
				if (c->comm.is_active_offline == 1) {	
					c->im.client.el->stop = 1; //change by tan 2018.10.18  退出while大循環
					//break;			//change by tan 2018.10.18 不用退出，一直檢測網絡
				}
				if (c->comm.is_force_offline != 1)
				{
					if (failed_count == 0)
					{
						c->comm.notify.on_im_error_notify(101);	//101 网络异常
						failed_count++;
						ok_count = 0;
					}
					//return;    //change by tan 2018.10.18 不用退出，一直檢測網絡
				}
				else
				{
					LOGI("c->comm.is_force_offline == 1");
					c->comm.is_force_offline = 0;
					//return;     //change by tan 2018.10.18 不用退出，一直檢測網絡
				}
			}
			else
			{
				LOGI("[INFO][sdk] thread_check_net ok");
				if (ok_count == 0)
				{
					c->comm.notify.on_im_error_notify(100); //網絡通
					ok_count++;
					failed_count = 0;
				}
			}
		
	}

	c->comm.notify.on_im_error_notify(102);	//102 进行了主动断开连接的操作	
	c->comm.is_active_offline = 0;
	return;
}


void * thread_check_net()
{
	SDK_CONTENT * c = &g_sdk_content;
	int ok_count = 0;
	int failed_count = 0;
	while (c->comm.is_active_offline == 0)	//如果没有进行主动断开连接的操作，则循环判断网络情况
	{
		LOGI("[INFO][sdk] thread_check_net looping ");
		sleep(5);

		if (0 != check_conn(c->im.client.fd))
		{
			sleep(1);
			c->im.net_status = 0;
			c->im.client.el->stop = 1;
			LOGI("[INFO][sdk] thread_check_net failed");
			if (c->comm.is_force_offline != 1)
			{
				if (failed_count == 0)
				{
					c->comm.notify.on_im_error_notify(101);	//101 网络异常
					failed_count++;
					ok_count = 0;
				}
				//return;									 //change by tan 2018.10.18 不用退出，一直檢測網絡
			}
			else
			{
				LOGI("c->comm.is_force_offline == 1");
				c->comm.is_force_offline = 0;
				//return;     //change by tan 2018.10.18 不用退出，一直檢測網絡
			}
		}
		else
		{
			LOGI("[INFO][sdk] thread_check_net ok");
			if (ok_count == 0)
			{
				c->comm.notify.on_im_error_notify(100); //網絡通
				ok_count++;
				failed_count = 0;
			}
		}

	}

	c->comm.notify.on_im_error_notify(102);	//102 进行了主动断开连接的操作	
	c->comm.is_active_offline = 0;
	return;
}

// ？？？
void check_net()
{
	pthread_t thread_id;
	pthread_create(&thread_id, NULL, &thread_check_net, NULL);
}
